package com.mashuai.utils.toolkit.core.msConverts;

import com.mashuai.utils.base.MsEmptyUtils;
import com.mashuai.utils.toolkit.achieve.MsExegesis;
import org.apache.poi.ss.formula.functions.T;

import java.util.Arrays;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * stream流常用写法
 *
 * @ClassName: MsStreamUtils
 * @Author : mashuai
 * @Description: TODO
 */
@MsExegesis("stream流常用写法")
public class MsStreamUtils {
    /**
     * List<Bean>转换成List<R>
     **/
    @MsExegesis("List<Bean>转换成List<R>")
    public static <T, R> List<R> listStreamMap(List<T> list, Function<T, R> fuc) {
        return list.stream().map(t -> fuc.apply(t)).collect(Collectors.toList());
    }

    /**
     * 对List集合某个字段值进行分组
     */
    @MsExegesis("对List集合某个字段值进行分组")
    public static <S, T> Map<S, List<T>> groupBy(List<T> list, Function<T, S> fuc) {
        return list.stream().filter(t -> MsEmptyUtils.isNotEmpty(fuc.apply(t))).collect(Collectors.groupingBy(fuc));
    }

    /**
     * 对List集合某个字段值进行分组，保证分组后的顺序不改变
     */
    @MsExegesis("对List集合某个字段值进行分组，保证分组后的顺序不改变")
    public static <S, T> Map<S, List<T>> groupByLink(List<T> list, Function<T, S> fuc) {
        return list.stream().collect(Collectors.groupingBy(fuc, LinkedHashMap::new, Collectors.toList()));
    }

    /**
     * 对List集合某个字段值进行分组，返回每组第一个
     */
    @MsExegesis(" 对List集合某个字段值进行分组，返回每组第一个")
    public static <S, T> Map<S, T> groupByT(List<T> list, Function<T, S> fuc) {
        return list.stream().filter(t -> MsEmptyUtils.isNotEmpty(fuc.apply(t))).collect(Collectors.toMap(fuc, java.util.function.Function.identity()));
    }

    /**
     * [{"name":"张三","hobby":"篮球;羽毛球;足球"},{"name":"李四","hobby":"网球"}]
     * 转换成：["篮球","羽毛球","足球","网球"]
     *
     * @param list
     * @param fuc
     * @param split
     * @param <T>
     */
    @MsExegesis("[{\"name\":\"张三\",\"hobby\":\"篮球;羽毛球;足球\"},{\"name\":\"李四\",\"hobby\":\"网球\"}]转换成：[\"篮球\",\"羽毛球\",\"足球\",\"网球\"]")
    public static <T> List<String> listSplit(List<T> list, Function<T, String> fuc, String split) {
        return list.stream()
                .flatMap(t -> fuc.apply(t) != null ? Arrays.stream(fuc.apply(t).split(split)) : null)
                .distinct()
                .collect(Collectors.toList());
    }

    /**
     * [{"name":"张三","hobby":"篮球;羽毛球;足球"},{"name":"李四","hobby":"网球"}]转换[张三,李四]
     */
    @MsExegesis(" [{\"name\":\"张三\",\"hobby\":\"篮球;羽毛球;足球\"},{\"name\":\"李四\",\"hobby\":\"网球\"}]转换[张三,李四]")
    public static <T, R> List<R> listStr(List<T> list, Function<T, R> fuc, Class<R> cla) {
        return list.stream().map(t -> fuc.apply(t)).collect(Collectors.toList());
    }

    /***
     * 获取map最大值得key
     * @param map
     * @return
     */
    @MsExegesis("获取map最大值得key")
    public static Object mapMaxValueKey(Map<Object, Integer> map) {
        return map.entrySet().stream().max(Map.Entry.comparingByValue()).get().getKey();
    }


}
